#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <strings.h>
#include <string>
#include<cerrno>
#include "ERRNO.hpp"

using namespace std;

void ClientHandler(int sock,string severip,uint16_t severport)
{
    struct sockaddr_in sever;
    sever.sin_family=AF_INET;
    sever.sin_addr.s_addr = inet_addr(severip.c_str());
    sever.sin_port = htons(severport);

    string message;    
    while(1)
    {
        cout<<"Enter>>";
        getline(cin,message);
        int n = write(sock,message.c_str(),message.size());
        if(n==0)
        break;
        if(n==-1)
        {
            cout<<"write error"<<endl;
            exit(WRITE_ERR);
        }
        //读取response
        char resp[1024];
        bzero(resp,sizeof resp);
        read(sock,resp,sizeof resp);
        string response = "sever response : ";
        response += resp;
        cout<<response<<endl;
    }
    
}



class client
{
public:
    client(uint16_t port, string ip)
        : _severport(port), _severip(ip)
    {
    }
    void init()
    {
        _sock = socket(AF_INET, SOCK_STREAM, 0);
        if (_sock == -1)
        {
            cout << "socket fail" << endl;
            // cout<<strerror(errno)<<endl;
            exit(SOCKET_ERR);
        }
        cout << "socket success" << endl;
        //不需要显式bind
    }
    void start()
    {
        struct sockaddr_in sever;
        sever.sin_addr.s_addr = inet_addr(_severip.c_str());
        sever.sin_port = htons(_severport);
        sever.sin_family = AF_INET;
        socklen_t len = sizeof sever;
        int n = connect(_sock,(struct sockaddr*)&sever,len);
        if(n!=0) 
        {
            cout<<"connect fail"<<endl;
            cout<<strerror(errno)<<endl;
            exit(CONNECT_ERR);
        }
        cout<<"connect success"<<endl;
        // 连接成功之后就是客户端的请求逻辑
        ClientHandler(_sock,_severip,_severport);
    
    }   

private:
    int _sock;
    string _severip;
    uint16_t _severport;
};
